/******************************************************************************
 * Copyright (C) 2015  671643387@qq.com
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 *****************************************************************************/

#include "logsystem.h"
#include <cstring>
#include "node/assert.h"
#include "node/system/lockguard.h"
#include "logger.h"

namespace node {
    namespace log {

        LogSystem *LogSystem::instance_ = NULL;

        LogSystem *LogSystem::instance(void)
        {
            NODE_ASSERT(instance_ != NULL);
            return instance_;
        }

        LogSystem::LogSystem(void)
            : logger_id_(0)
            , loggers_lock_()
        {
            NODE_ASSERT(instance_ == NULL);
            instance_ = this;
            memset(&loggers_[0], 0, sizeof(loggers_));
        }

        LogSystem::~LogSystem(void)
        {

        }

        bool LogSystem::initialize(void)
        {
            return true;
        }

        void LogSystem::uninitialize(void)
        {
            clearLoggers();
        }

        Logger *LogSystem::newLogger(const char *dir, const char *name)
        {
            NODE_ASSERT(logger_id_ < MAX_LOGGER);
            if (logger_id_ >= MAX_LOGGER) {
                return NULL;
            }

            NODE_GUARD_LOCK_ASSERT_RETURN_VAR(loggers_lock_, NULL);
            Logger *logger = new Logger(dir, name);
            if (logger) {
                loggers_[logger_id_] = logger;
                logger->id_ = logger_id_;
                ++logger_id_;
                return logger;
            }
            return NULL;
        }

        void LogSystem::freeLogger(Logger* logger)
        {
            NODE_GUARD_LOCK_ASSERT_RETURN(loggers_lock_);
            NODE_ASSERT((logger->id_ < MAX_LOGGER) 
                && (loggers_[logger->id_] == logger));
            if ((logger->id_ < MAX_LOGGER) 
                && (loggers_[logger->id_] == logger))
            {
                loggers_[logger->id_] = NULL;
            }
            delete logger;
        }

        void LogSystem::freeLogger(const char *name)
        {
            NODE_GUARD_LOCK_ASSERT_RETURN(loggers_lock_);
            for (int x = 0; x < MAX_LOGGER; ++x)
            {
                if ((loggers_[x] != NULL) 
                    && (strcmp(name, loggers_[x]->name_.c_str()) == 0))
                {
                    delete loggers_[x];
                    loggers_[x] = NULL;
                    break;
                }
            }
        }

        Logger *LogSystem::getLogger(const char *name)
        {
            for (int x = 0; x < MAX_LOGGER; ++x)
            {
                if ((loggers_[x] != NULL) 
                    && (strcmp(name, loggers_[x]->name_.c_str()) == 0))
                {
                    return loggers_[x];
                }
            }
            NODE_ASSERT(false);
            return NULL;
        }

        void LogSystem::clearLoggers(void)
        {
            NODE_GUARD_LOCK_ASSERT_RETURN(loggers_lock_);
            for (int x = 0; x < MAX_LOGGER; ++x)
            {
                if (loggers_[x] != NULL)
                {
                    delete loggers_[x];
                    loggers_[x] = NULL;
                    break;
                }
            }
        }
    }
}